using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;

/// <summary>
/// UI层级
/// </summary>
public enum E_UI_Layer
{
    Bot,
    Mid,
    Top,
    System
}

/// <summary>
/// 面板基类
/// 找到所有自己面板下的控件对象
/// 提供显示，隐藏的行为
/// </summary>
public class UIMgr : Singleton<UIMgr>
{
    public Dictionary<string, BasePanel> panelDic = new Dictionary<string, BasePanel>();

    //底层
    private Transform bot;
    //中层
    private Transform mid;
    //顶层
    private Transform top;
    //系统
    private Transform system;

    //记录UI的Canvas父对象 方便外部使用
    public RectTransform canvas;

    public UIMgr()
    {
        //创建Canvas 过场景不被移除
        GameObject obj = ResMgr.GetInstance().Load<GameObject>("UI/Canvas");
        canvas = obj.transform as RectTransform;
        GameObject.DontDestroyOnLoad(obj);

        //层级
        bot = canvas.Find("Bot");
        mid = canvas.Find("Mid");
        top = canvas.Find("Top");
        system = canvas.Find("System");

        //创建EventSystem 过场景不被移除
        obj = ResMgr.GetInstance().Load<GameObject>("UI/EventSystem");
        GameObject.DontDestroyOnLoad(obj);
    }

    /// <summary>
    /// 显示面板
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="panelName"></param>
    /// <param name="layer"></param>
    /// <param name="callback"></param>
    public void ShowPanel<T>(E_UI_Layer layer, UnityAction<T> callback) where T : BasePanel
    {
        //需要保证 泛型T的类型和面板名一致
        string panelName = typeof(T).Name;
        if (panelDic.ContainsKey(panelName))
        {
            T panel = panelDic[panelName] as T;
            panel.Show();
            callback?.Invoke(panelDic[panelName] as T);
            return;
        }
        ResMgr.GetInstance().LoadAsync<GameObject>("UI/" + panelName, (obj) =>
        {
            //将其设置为Canvas的子对象,设置相对位置
            Transform father = null;
            switch (layer)
            {
                case E_UI_Layer.Bot:
                    father = bot;
                    break;
                case E_UI_Layer.Mid:
                    father = mid;
                    break;
                case E_UI_Layer.Top:
                    father = top;
                    break;
                case E_UI_Layer.System:
                    father = system;
                    break;
            }
            //设置父对象
            obj.transform.SetParent(father);
            //设置相对位置和大小
            obj.transform.localPosition = Vector3.zero;
            obj.transform.localScale = Vector3.one;
            (obj.transform as RectTransform).offsetMax = Vector2.zero;
            (obj.transform as RectTransform).offsetMin = Vector2.zero;

            //得到预设体身上的面板脚本
            T panel = obj.GetComponent<T>();
            callback?.Invoke(panel);

            panel.Show();
            panelDic.Add(panelName, panel);
        });
    }

    /// <summary>
    /// 隐藏面板
    /// </summary>
    /// <param name="panelName"></param>
    public void HidePanel<T>()
    {
        string panelName = typeof(T).Name;
        if (!panelDic.ContainsKey(panelName))
            return;
        GameObject.Destroy(panelDic[panelName].gameObject);
        panelDic.Remove(panelName);
        Debug.LogFormat("[UIMgr][HidePanel] panel:{0}", panelName);
    }

    /// <summary>
    /// 获取面板
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public T GetPanel<T>() where T : BasePanel
    {
        string panelName = typeof(T).Name;
        if (!panelDic.ContainsKey(panelName))
            return null;
        return panelDic[panelName] as T;
    }

    /// <summary>
    /// 获取父亲对象层级
    /// </summary>
    /// <param name="layer"></param>
    /// <returns></returns>
    public Transform GetLayerFather(E_UI_Layer layer)
    {
        switch (layer)
        {
            case E_UI_Layer.Bot:
                return this.bot;
            case E_UI_Layer.Mid:
                return this.mid;
            case E_UI_Layer.Top:
                return this.top;
            case E_UI_Layer.System:
                return this.system;
        }
        return null;
    }

    /// <summary>
    /// 给控件添加自定义事件监听
    /// </summary>
    /// <param name="control"></param>
    /// <param name="type"></param>
    /// <param name="callback"></param>
    public static void AddCustomEventListener(UIBehaviour control, EventTriggerType type, UnityAction<BaseEventData> callback)
    {
        EventTrigger trigger = control.gameObject.GetComponent<EventTrigger>();
        if (trigger == null)
            trigger = control.gameObject.AddComponent<EventTrigger>();
        EventTrigger.Entry entry = new EventTrigger.Entry();
        entry.eventID = type;
        entry.callback.AddListener(callback);
        trigger.triggers.Add(entry);
    }
}
